﻿/*:
 * @plugindesc （新枫之舞专用）分身战斗
 * @author 小c、老饕
 *
 * @param Doppelganger Move Frame
 * @text 分身移动时间
 * @type number
 * @min 1
 * @default 60
 * @desc 分身移向中心分身需要的时间，单位：帧，从中心移回原位需要相同的时间
 *
 * @param Doppelganger Wait Frame
 * @text 分身合并等待时间
 * @type number
 * @min 1
 * @default 10
 * @desc 分身合并后到分身开始散开中间等待的时间，单位：帧
 *
 * @param Doppelganger Change Master Code
 * @text 分身切换额外代码
 * @type note
 * @default ""
 * @desc 真身切换时指定执行的额外内容，这里this指$gameTroop
 *
 * @param For All Useless
 * @text 群攻无效
 * @type boolean
 * @on 群攻无效
 * @off 群攻有效
 * @default true
 * 
 * @help 
 * 新枫之舞专用，分身忍者战斗机制。
 * 需要YEP战斗核心支持
 * 需要将它放在CP_SWDA_BaseData的下面
 *
 * 使用方法：分身忍者战斗，数据库需要3个同样的敌人
 *
 * 敌群事件，第一页事件注释【不管第一页事件是否执行都是有效的】：
 * 分身定义：
 * <Enemy Doppelganger List: x, x, x>
 * 指定所有分身敌人的序号，x≥1
 * 例：<Enemy Doppelganger List: 1, 2, 3>
 * 指定1 2 3号敌人为一组分身，这里1号敌人指$gameTroop.members()[0]，以此类
 * 推
 * 中心定义：
 * <Enemy Doppelganger Center: x>
 * 指定分身的中心敌人为x，x必须是分身之一
 * 分身中心敌人：分身切换时执行分身合并和分身散开动画的中心对象
 * 战斗开始时只会显示中心敌人
 * 例：<Enemy Doppelganger Center: 2>
 * 设置第二个敌人为中心
 *
 * 分身切换：以下JS脚本将执行分身切换动画并【随机】切换真身
 * $gameTroop.startChangeDoppelgangerMaster()
 * 执行分身切换时战斗会暂时阻塞直到所有动画播放完毕
 * 分身切换后会执行一个响应代码，内容由插件参数决定
 *
 * 敌人AI指定时可以用以下函数判定是否为真身
 * 敌人的成员函数有如下几个：
 * enemy.isDoppelganger() 是否为分身之一【包括真身和分身都是true】
 * 非分身战斗中其他敌人调用会返回false
 * enemy.isDoppelgangerMaster() 是否为分身真身，非分身战斗中不要调用
 * enemy.masterDoppelganger() 返回战斗中当前的真身，非分身战斗中返回null
 * enemy.isDoppelgangerCenter() 是否为中心对象，非分身战斗中返回false
 * enemy.isInvincibleByDoppelganger() 是否为分身假身，分身假身无敌
 * 非分身战斗中返回false，不要调用
 * enemy.isDoppelgangerCenter() 是否为中心敌人，非分身战斗返回false
 *
 * Game_Troop类相关函数：
 * $gameTroop.doppelgangerEnemies() 所有分身敌人
 * 注意：返回数组长度如果小于2，hasDoppelgangerEnemy返回false
 * $gameTroop.hasDoppelgangerEnemy() 战斗是否存在分身敌人
 * $gameTroop.masterDoppelgangerEnemy() 返回当前真身
 * $gameTroop.centerDoppelgangerEnemy() 返回中心敌人对象
 *
 * 实际配置敌群可如下操作：
 * 1. 添加若干相同的敌人作为分身敌人
 * 2. 需要的话此时可进入战斗测试确定每个敌人的实际位置
 * 3. 配置分身的两个标签
 * 4. 第0回合必须执行一次分身切换
 * 5. 分身切换的执行可以通过事件脚本或者技能效果
 * (1) 事件脚本的执行是有规律的，因此执行条件一般是回合数【0+nX】
 * (2) 如果是技能效果，可以通过战斗序列的Eval指令实现，执行条件参考(1)
*/

var Imported = Imported || {};
Imported.CP_Doppelganger = true;

var CP = CP || {};
CP.Doppelganger = CP.Doppelganger || {};
CP.Doppelganger.Params = PluginManager.parameters("CP_Doppelganger");
CP.Doppelganger.DOPPELGANGER_MOVE_FRAME = Number(CP.Doppelganger.Params["Doppelganger Move Frame"]) || 0;
CP.Doppelganger.DOPPELGANGER_WAIT_FRAME = Number(CP.Doppelganger.Params["Doppelganger Wait Frame"]) || 0;
CP.Doppelganger.DOPPELGANGER_CHANGE_MASTER_CODE = new Function(JSON.parse(CP.Doppelganger.Params["Doppelganger Change Master Code"]));
CP.Doppelganger.ITEM_FOR_ALL_USELESS = eval(CP.Doppelganger.Params["For All Useless"]) || false;

//-----------------------------------------
// Game_Troop
//-----------------------------------------
CP.Doppelganger.SETUP_TROOP = Game_Troop.prototype.setup;
Game_Troop.prototype.setup = function(troopId){
	this._doppelgangerEnemies = null;
	CP.Doppelganger.SETUP_TROOP.call(this, troopId);
	this.loadDoppelgangerEnemies();
	this.initDoppelgangerMaster();
};

Game_Troop.prototype.loadDoppelgangerEnemies = function(){
	var list = this.troop().pages[0].list;
	var reg1 = /<Enemy Doppelganger List: ([\S\s]+)>/;
	var reg2 = /<Enemy Doppelganger Center: (\d+)>/;

	this._doppelgangerEnemies = []; //分身的敌人数组，当数组长度至少为2时，此战斗才是分身战斗
	this._doppelgangerCenterEnemy = 0; //分身中心敌人，当分身交换时，所有分身敌人向中心靠拢然后散开回原位

	list.forEach(function(ev){
		if([108, 408].contains(ev.code)){
			if(reg1.exec(ev.parameters[0])){
				var doppelgangerList = RegExp.$1.trim().split(",").map(function(chars){
					return Number(chars) || 0;
				});
				for(var i = 0; i < doppelgangerList.length; i++){
					if(doppelgangerList[i] > 0)
						this._doppelgangerEnemies.push(doppelgangerList[i]);
				}
			}

			if(reg2.exec(ev.parameters[0]))
				this._doppelgangerCenterEnemy = Number(RegExp.$1) || 0;
		}
	}, this);
};

//所有的分身敌人【没有考虑主目标问题】
Game_Troop.prototype.doppelgangerEnemies = function(){
	if(!this._doppelgangerEnemies)
		return [];
	var results = [];
	var members = this.members();
	for(var i = 0; i < this._doppelgangerEnemies.length; i++){
		var index = this._doppelgangerEnemies[i] - 1;
		results.push(members[index]);
	}
	return results;
};

Game_Troop.prototype.hasDoppelgangerEnemy = function(){
	return this.doppelgangerEnemies().length > 1;
};

//分身主体对象
Game_Troop.prototype.masterDoppelgangerEnemy = function(){
	if(this.hasDoppelgangerEnemy()){
		var enemies = this.doppelgangerEnemies();
		for(var i = 0; i < enemies.length; i++){
			var enemy = enemies[i];
			if(enemy.isDoppelgangerMaster())
				return enemy;
		}
		return null;
	}else
		return null;
};

//初始化分身主体
Game_Troop.prototype.initDoppelgangerMaster = function(){
	var enemies = this.doppelgangerEnemies();
	if(enemies.length > 0){
		var enemy = enemies[Math.floor(Math.random() * enemies.length)];
		if(!!enemy)
			enemy.setDoppelgangerMaster(true);
	}
};

//随机切换主体
Game_Troop.prototype.changeDoppelgangerMaster = function(){
	var enemies = this.doppelgangerEnemies();
	var data = this.getDoppelgangerMasterData();
	var newMasterIndex = Math.floor(Math.random() * enemies.length);
	for(var i = 0; i < enemies.length; i++){
		var enemy = enemies[i];
		if(i === newMasterIndex){
			enemy.setDoppelgangerMaster(true);
			enemy.resetDoppelgangerData(data);
		}else
			enemy.setDoppelgangerMaster(false);
	}

};

Game_Troop.prototype.getDoppelgangerMasterData = function(){
	var data = {states: [], stateTurns: {}, statesFloor: [], classId: -1};
	var master = this.masterDoppelgangerEnemy();
	if(!!master){
		data.states = master.statesData();
		data.stateTurns = master.stateTurnsData();
		data.statesFloor = master.statesFloorData();
		data.classId = master.currentClass().id;
	}
	return data;
};

Game_Troop.prototype.centerDoppelgangerEnemy = function(){
	if(this.hasDoppelgangerEnemy()){
		var enemy = this.members()[this._doppelgangerCenterEnemy - 1];
		if(!!enemy)
			return enemy;
		else
			return null;
	}else
		return null;
};

//开始执行主体切换，包括移动到中心、切换主体、移动分散
Game_Troop.prototype.startChangeDoppelgangerMaster = function(){
	var centerDoppelgangerEnemy = this.centerDoppelgangerEnemy();
	var doppelgangerEnemies = this.doppelgangerEnemies();
	if(!!centerDoppelgangerEnemy){
		var centerSprite = centerDoppelgangerEnemy.battler();
		for(var i = 0; i < doppelgangerEnemies.length; i++){
			var enemy = doppelgangerEnemies[i];
			enemy.battler().startToDoppelgangerCenterEnemy(centerSprite
				, CP.Doppelganger.DOPPELGANGER_MOVE_FRAME);
		}
	}
	this.changeDoppelgangerMaster();
	this.onDoppelgangerMasterChanged();
};

Game_Troop.prototype.onDoppelgangerMasterChanged = function(){
	try{
		CP.Doppelganger.DOPPELGANGER_CHANGE_MASTER_CODE.call(this);
	}catch(err){
		console.error(err);
	}
};

CP.Doppelganger.TROOP_ON_BATTLE_END = Game_Troop.prototype.onBattleEnd;
Game_Troop.prototype.onBattleEnd = function(){
	CP.Doppelganger.TROOP_ON_BATTLE_END.call(this);
	this._doppelgangerEnemies = null;
};

//-----------------------------------------
// Game_BattlerBase
//-----------------------------------------
//分身假身
Game_BattlerBase.prototype.isInvincibleByDoppelganger = function(){
	return false;
};

//无敌数据相关
//无敌的属性效果
CP.Doppelganger.BATTLER_PARAM = Game_BattlerBase.prototype.param;
Game_BattlerBase.prototype.param = function(paramId){
	if(this.isInvincibleByDoppelganger()){
		var master = this.masterDoppelganger();
		if(!!master)
			return CP.Doppelganger.BATTLER_PARAM.call(master, paramId);
		else
			return CP.Doppelganger.BATTLER_PARAM.call(this, paramId);
	}else
		return CP.Doppelganger.BATTLER_PARAM.call(this, paramId);
};

CP.Doppelganger.BATTLER_XPARAM = Game_BattlerBase.prototype.xparam;
Game_BattlerBase.prototype.xparam = function(xparamId){
	if(this.isInvincibleByDoppelganger()){
		var master = this.masterDoppelganger();
		if(!!master)
			return CP.Doppelganger.BATTLER_XPARAM.call(master, xparamId);
		else
			return CP.Doppelganger.BATTLER_XPARAM.call(this, xparamId);
	}else
		return CP.Doppelganger.BATTLER_XPARAM.call(this, xparamId);
};

CP.Doppelganger.BATTLER_SPARAM = Game_BattlerBase.prototype.sparam;
Game_BattlerBase.prototype.sparam = function(sparamId){
	if(this.isInvincibleByDoppelganger()){
		var master = this.masterDoppelganger();
		if(!!master)
			return CP.Doppelganger.BATTLER_SPARAM.call(master, sparamId);
		else
			return CP.Doppelganger.BATTLER_SPARAM.call(this, sparamId);
	}else
		return CP.Doppelganger.BATTLER_SPARAM.call(this, sparamId);
};

//无敌的状态效果
CP.Doppelganger.BATTLER_STATES = Game_BattlerBase.prototype.states;
Game_BattlerBase.prototype.states = function(){
	if(this.isInvincibleByDoppelganger()){
		var master = this.masterDoppelganger();
		if(!!master)
			return CP.Doppelganger.BATTLER_STATES.call(master);
		else
			return CP.Doppelganger.BATTLER_STATES.call(this);
	}else
		return CP.Doppelganger.BATTLER_STATES.call(this);
};

CP.Doppelganger.BATTLER_STATE_AFFECTED = Game_BattlerBase.prototype.isStateAffected;
Game_BattlerBase.prototype.isStateAffected = function(stateId){
	if(this.isInvincibleByDoppelganger()){
		var master = this.masterDoppelganger();
		if(!!master)
			return CP.Doppelganger.BATTLER_STATE_AFFECTED.call(master, stateId);
		else
			return CP.Doppelganger.BATTLER_STATE_AFFECTED.call(this, stateId);
	}else
		return CP.Doppelganger.BATTLER_STATE_AFFECTED.call(this, stateId);
};

CP.Doppelganger.BATTLER_STATE_FLOOR = Game_BattlerBase.prototype.stateFloor;
Game_BattlerBase.prototype.stateFloor = function(stateId){
	if(this.isInvincibleByDoppelganger()){
		var master = this.masterDoppelganger();
		if(!!master)
			return CP.Doppelganger.BATTLER_STATE_FLOOR.call(master, stateId);
		else
			return CP.Doppelganger.BATTLER_STATE_FLOOR.call(this, stateId);
	}else
		return CP.Doppelganger.BATTLER_STATE_FLOOR.call(this, stateId);
};

//-----------------------------------------
// Game_Battler
//-----------------------------------------
//无敌数据相关
//无敌的属性效果
CP.Doppelganger.BATTLER_GAIN_HP = Game_Battler.prototype.gainHp;
Game_Battler.prototype.gainHp = function(value){
	if(this.isInvincibleByDoppelganger())
		CP.Doppelganger.BATTLER_GAIN_HP.call(this, 0);
	else
		CP.Doppelganger.BATTLER_GAIN_HP.call(this, value);
};

CP.Doppelganger.BATTLER_GAIN_MP = Game_Battler.prototype.gainMp;
Game_Battler.prototype.gainMp = function(value){
	if(this.isInvincibleByDoppelganger())
		CP.Doppelganger.BATTLER_GAIN_MP.call(this, 0);
	else
		CP.Doppelganger.BATTLER_GAIN_MP.call(this, value);
};

CP.Doppelganger.BATTLER_GAIN_TP = Game_Battler.prototype.gainTp;
Game_Battler.prototype.gainTp = function(value){
	if(this.isInvincibleByDoppelganger())
		CP.Doppelganger.BATTLER_GAIN_TP.call(this, 0);
	else
		CP.Doppelganger.BATTLER_GAIN_TP.call(this, value);
};

CP.Doppelganger.BATTLER_GAIN_SILENT_TP = Game_Battler.prototype.gainSilentTp;
Game_Battler.prototype.gainSilentTp = function(value){
	if(this.isInvincibleByDoppelganger())
		CP.Doppelganger.BATTLER_GAIN_SILENT_TP.call(this, 0);
	else
		CP.Doppelganger.BATTLER_GAIN_SILENT_TP.call(this, value);
};

//无敌的状态效果
//除了死亡，分身免疫所有状态
CP.Doppelganger.BATTLER_STATE_ADDABLE = Game_Battler.prototype.isStateAddable;
Game_Battler.prototype.isStateAddable = function(stateId){
	if(this.isInvincibleByDoppelganger())
		return CP.Doppelganger.BATTLER_STATE_ADDABLE.call(this, stateId) 
			&& stateId === this.deathStateId();
	else
		return CP.Doppelganger.BATTLER_STATE_ADDABLE.call(this, stateId);
};

CP.Doppelganger.BATTLER_ADD_BUFF = Game_Battler.prototype.addBuff;
Game_Battler.prototype.addBuff = function(paramId, turns){
	if(!this.isInvincibleByDoppelganger())
		CP.Doppelganger.BATTLER_ADD_BUFF.call(this, paramId, turns);
};

CP.Doppelganger.BATTLER_ADD_DEBUFF = Game_Battler.prototype.addDebuff;
Game_Battler.prototype.addDebuff = function(paramId, turns){
	if(!this.isInvincibleByDoppelganger())
		CP.Doppelganger.BATTLER_ADD_DEBUFF.call(this, paramId, turns);
};

//-----------------------------------------
// Game_Enemy
//-----------------------------------------
CP.Doppelganger.ENEMY_INIT_MEMBERS = Game_Enemy.prototype.initMembers;
Game_Enemy.prototype.initMembers = function(){
	CP.Doppelganger.ENEMY_INIT_MEMBERS.call(this);
	this._doppelgangerMaster = false; //分身主体标记，只有分身主体才会受到伤害
};

Game_Enemy.prototype.statesData = function(){
	return this._states;
};

Game_Enemy.prototype.stateTurnsData = function(){
	return this._stateTurns;
};

Game_Enemy.prototype.statesFloorData = function(){
	return this._statesFloor;
};

Game_Enemy.prototype.resetDoppelgangerData = function(data){
	this._states = data.states;
	this._stateTurns = data.stateTurns;
	this._statesFloor = data.statesFloor;
	if(data.classId > 0)
		this._classId = data.classId;
	this.refresh();
};

//该敌人是否为分身对象：即是否为定义的分身目标之一
Game_Enemy.prototype.isDoppelganger = function(){
	return $gameTroop.doppelgangerEnemies().contains(this);
};

//设置是否为分身主体
Game_Enemy.prototype.setDoppelgangerMaster = function(value){
	this._doppelgangerMaster = !!value;
};

Game_Enemy.prototype.isDoppelgangerMaster = function(){
	return !!this._doppelgangerMaster;
};

//分身主体对象
Game_Enemy.prototype.masterDoppelganger = function(){
	if(this.isDoppelganger() && this.isDoppelgangerMaster())
		return this;
	else
		return $gameTroop.masterDoppelgangerEnemy();
};

//是否因分身而无敌：非主体的分身敌人是无敌的，受伤永远为0，免疫除死亡以外的所有状态
//另：带有这个效果的敌人，所有属性与分身主体完全一致，因此计算属性时也可调用该函数
Game_Enemy.prototype.isInvincibleByDoppelganger = function(){
	return this.isDoppelganger() && !this.isDoppelgangerMaster();
};

//中心敌人：分身从这个敌人这里散开
Game_Enemy.prototype.isDoppelgangerCenter = function(){
	return this.isDoppelganger() && this === $gameTroop.centerDoppelgangerEnemy();
};

CP.Doppelganger.ENEMY_CURRENT_CLASS = Game_Enemy.prototype.currentClass;
Game_Enemy.prototype.currentClass = function(){
	if(this.isInvincibleByDoppelganger()){
		var master = this.masterDoppelganger();
		if(!!master)
			return CP.Doppelganger.ENEMY_CURRENT_CLASS.call(master);
		else
			return CP.Doppelganger.ENEMY_CURRENT_CLASS.call(this);
	}else
		return CP.Doppelganger.ENEMY_CURRENT_CLASS.call(this);
};

//数据（血蓝等）同步刷新机制
Game_Enemy.prototype.refresh = function(){
	if(!this.isDoppelganger()) //不是分身对象，正常刷新 补充：如果存在其他的插件写了enemy.refresh，这里改成自调用
		Game_Battler.prototype.refresh.call(this);
	else if(this.isDoppelgangerMaster()){
		//分身主体，需要触发自身和所有分身的刷新
		//分身状态会负责所有分身对象的刷新，因此非主体对象不需要在这里调用刷新【else if下面没有else】
		//分身对象刷新使用refreshDoppelganger函数
		var doppelgangerEnemies = $gameTroop.doppelgangerEnemies();
		for(var i = 0; i < doppelgangerEnemies.length; i++){
			var e = doppelgangerEnemies[i];
			e.refreshDoppelganger();
		}
	}
};

Game_Enemy.prototype.refreshDoppelganger = function(){
	if(!this.isDoppelgangerMaster())
		this.refreshDoppelgangerData();
	//补充：如果存在其他的插件写了enemy.refresh，这里改成自调用
	Game_Battler.prototype.refresh.call(this);
};

Game_Enemy.prototype.refreshDoppelgangerData = function(){
	if(this.isInvincibleByDoppelganger()){
		var master = this.masterDoppelganger();
		if(!!master)
			this.setDoppelgangerData(master);
	}
};

Game_Enemy.prototype.setDoppelgangerData = function(master){
	this._hp = master.hp;
	this._mp = master.mp;
	this._tp = master.tp;
	if(!(this.isATBCharging() || this.masterDoppelganger().isATBCharging()))
		this._atbSpeed = master._atbSpeed;	//SWDA：同步ATB
	if(this._hp <= 0 && master.isDead())
		this.performCollapse();
};

//---------------------------------------
// Game_Action
//---------------------------------------
//群攻无效对伤害的影响
CP.Doppelganger.ACTION_MAKE_DAMAGE_VALUE = Game_Action.prototype.makeDamageValue;
Game_Action.prototype.makeDamageValue = function(target, critical){
	if(CP.Doppelganger.ITEM_FOR_ALL_USELESS && this.isForAll() && target.isEnemy() && target.isDoppelganger() 
			&& target.isDoppelgangerMaster())
		return 0; //群攻对分身敌人 当群攻无效时返回0
	else
		return CP.Doppelganger.ACTION_MAKE_DAMAGE_VALUE.call(this, target, critical);
};

//群攻无效对额外效果的影响
CP.Doppelganger.ACTION_APPLY_ITEM_EFFECT = Game_Action.prototype.applyItemEffect;
Game_Action.prototype.applyItemEffect = function(target, effect){
	if(!CP.Doppelganger.ITEM_FOR_ALL_USELESS || !this.isForAll() 
			|| !target.isEnemy() || !target.isDoppelganger())
		CP.Doppelganger.ACTION_APPLY_ITEM_EFFECT.call(this, target, effect);
};

//---------------------------------------
// Scene_Battle
//---------------------------------------
//当敌人分身在移动动画的时候，阻塞战斗
CP.Doppelganger.SCENE_BATTLE_IS_BUSY = Scene_Battle.prototype.isBusy;
Scene_Battle.prototype.isBusy = function(){
	if(this._spriteset.hasDoppelgangerMoving())
		return true;
	return CP.Doppelganger.SCENE_BATTLE_IS_BUSY.call(this);
};

//---------------------------------------
// Spriteset_Battle
//---------------------------------------
Spriteset_Battle.prototype.enemySprites = function() {
    return this._enemySprites;
};

Spriteset_Battle.prototype.hasDoppelgangerMoving = function(){
	var sprites = this.enemySprites();
	for(var i = 0; i < sprites.length; i++){
		if(sprites[i].isDoppelgangerMoving())
			return true;
	}
	return false;
};

//---------------------------------------
// Sprite_Enemy
//---------------------------------------
CP.Doppelganger.SPRITE_ENEMY_INIT_MEMBERS = Sprite_Enemy.prototype.initMembers;
Sprite_Enemy.prototype.initMembers = function(){
	this._moveDoppelgangerStart = false; //分身收移动标记
	this._moveDoppelgangerEnd = false; //分身散移动标记
	this._moveDoppelgangerFrame = 0; //分身移动持续时间【帧】
	this._doppelgangerVisible = false; //开场分身必须隐藏
	this._doppelgangerWaitFrame = -1; //分身合并-分散中间的等待帧
	CP.Doppelganger.SPRITE_ENEMY_INIT_MEMBERS.call(this);
};

Sprite_Enemy.prototype.setDoppelgangerWaitFrame = function(frame){
	if(frame > 0)
		this._doppelgangerWaitFrame = frame;
};

Sprite_Enemy.prototype.homeX = function(){
	return this._homeX;
};

Sprite_Enemy.prototype.homeY = function(){
	return this._homeY;
};

Sprite_Enemy.prototype.startToDoppelgangerCenterEnemy = function(centerEnemySprite, frame){
	if(this === centerEnemySprite)
		return;
	var offsetX = centerEnemySprite.homeX() - this._homeX;
	var offsetY = centerEnemySprite.homeY() - this._homeY;

	this._moveDoppelgangerStart = true;
	this._moveDoppelgangerFrame = frame;
	//当分身目标不是中心而不可见时，移动到中心的时间减半
	//因为这个时候这些移动目标是不可见的，不需要太多时间
	if(!this._doppelgangerVisible)
		frame = Math.floor(frame / 2);
	this.startMove(offsetX, offsetY, frame);
};

CP.Doppelganger.SPRITE_ENEMY_ON_MOVE_END = Sprite_Enemy.prototype.onMoveEnd;
Sprite_Enemy.prototype.onMoveEnd = function(){
	CP.Doppelganger.SPRITE_ENEMY_ON_MOVE_END.call(this);
	this._doppelgangerVisible = true;
	if(this._moveDoppelgangerStart && this._moveDoppelgangerFrame > 0)
		this.setDoppelgangerWaitFrame(CP.Doppelganger.DOPPELGANGER_WAIT_FRAME);
	else if(this._moveDoppelgangerEnd)
		this._moveDoppelgangerEnd = false;
};

CP.Doppelganger.SPRITE_ENEMY_UPDATE = Sprite_Enemy.prototype.update;
Sprite_Enemy.prototype.update = function(){
	CP.Doppelganger.SPRITE_ENEMY_UPDATE.call(this);
	this.updateDoppelgangerWaitCount(); //有粉散则执行分散
};

CP.Doppelganger.SPRITE_ENEMY_UPDATE_VISIBILITY = Sprite_Enemy.prototype.updateVisibility;
Sprite_Enemy.prototype.updateVisibility = function(){
	if(!!this._enemy && this._enemy.isDoppelgangerCenter())
		this._doppelgangerVisible = true;
	CP.Doppelganger.SPRITE_ENEMY_UPDATE_VISIBILITY.call(this);
	if(!!this._enemy && this._enemy.isDoppelganger() && !this._doppelgangerVisible)
		this.visible = false;
};

Sprite_Enemy.prototype.updateDoppelgangerWaitCount = function(){
	if(this._doppelgangerWaitFrame > 0){
		this._doppelgangerWaitFrame--;
		if(this._doppelgangerWaitFrame <= 0){
			this.startMove(0, 0, this._moveDoppelgangerFrame);
			this._moveDoppelgangerStart = false;
			this._moveDoppelgangerFrame = 0;
			this._moveDoppelgangerEnd = true;
			this._doppelgangerWaitFrame = -1;
		}
	}
};

//分身动画是否在运行【移动】，如果在运行，战斗必须阻塞
Sprite_Enemy.prototype.isDoppelgangerMoving = function(){
	if(!this._enemy)
		return false;
	if(!this._enemy.isDoppelganger())
		return false;
	if(this._moveDoppelgangerStart || this._moveDoppelgangerEnd)
		return true;
	return false;
};